<template>
  <div class="flaaa">
    <canvas id="three"></canvas>
  </div>
</template>

<script setup>
import * as THREE from 'three';
import { onMounted } from "vue";
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

async function loadModel() {
  return new Promise((resolve, reject) => {
    const gltfLoader = new GLTFLoader();
    gltfLoader.load("/flaaa/parent.gltf", (gltf) => {
      resolve(gltf.scene);
    }, undefined, reject);
  });
}

function initScene() {
  const scene = new THREE.Scene();
  scene.background = new THREE.Color("#eee");
  scene.fog = new THREE.Fog('#eee', 20, 100);
  return scene;
}

function initRenderer() {
  const threeDemo = document.getElementById("three");
  const renderer = new THREE.WebGLRenderer({ canvas: threeDemo, antialias: true });
  renderer.shadowMap.enabled = true;
  return renderer;
}

function initCamera() {
  const camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.position.z = 10;
  return camera;
}

function initLights(scene) {
  const dirLight = new THREE.DirectionalLight(0xffffff, 0.6);
  dirLight.position.set(-10, 6, -5);
  dirLight.castShadow = true;
  dirLight.shadow.mapSize = new THREE.Vector2(1024, 1024);
  scene.add(dirLight);

  const hemLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.6);
  hemLight.position.set(0, 46, 0);
  scene.add(hemLight);
}

function initFloor(scene) {
  const floorGeometry = new THREE.PlaneGeometry(3000, 3000);
  const floorMaterial = new THREE.MeshPhongMaterial({ color: "#7e7ab0" });
  const floorMesh = new THREE.Mesh(floorGeometry, floorMaterial);
  floorMesh.rotation.x = -0.5 * Math.PI;
  floorMesh.receiveShadow = true;
  floorMesh.position.y = -2;
  scene.add(floorMesh);
}

function resizeDevicePixel(renderer) {
  const canvas = renderer.domElement;
  const width = window.innerWidth;
  const height = window.innerHeight;
  const devicePixelWidth = canvas.width / window.devicePixelRatio;
  const devicePixelHeight = canvas.height / window.devicePixelRatio;

  const needResize = devicePixelWidth !== width || devicePixelHeight !== height;
  if (needResize) {
    renderer.setSize(width, height, false);
  }
  return needResize;
}

function animate(renderer, scene, camera, controls) {
  controls.update();
  renderer.render(scene, camera);
  requestAnimationFrame(() => animate(renderer, scene, camera, controls));

  if (resizeDevicePixel(renderer)) {
    const canvas = renderer.domElement;
    camera.aspect = canvas.clientWidth / canvas.clientHeight;
    camera.updateProjectionMatrix();
  }
}

onMounted(async () => {
  const scene = initScene();
  const renderer = initRenderer();
  const camera = initCamera();
  const controls = new OrbitControls(camera, renderer.domElement);

  initLights(scene);
  initFloor(scene);

  const model = await loadModel();
  model.position.y = -2;
  model.scale.set(0.3, 0.3, 0.3);
  scene.add(model);

  animate(renderer, scene, camera, controls);
});
</script>

<style scoped lang="less">
.flaaa {
  width: 98vw;
  height: 98vh;
}
#three {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}
</style>
